<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/8/16 0016
 * Time: 下午 4:44
 */

namespace App\Extend\Wx;


use App\Exceptions\WxLoginException;
use App\Extend\Wx\Exception\WxException;
use GuzzleHttp\Client;

class Wx
{
    //微信小程序APP_ID
    protected $appid;
    //微信小程序secret
    protected $secret;
    //微信小程序认证方式
    protected $grant_type = 'authorization_code';
    //小程序登录地址
    protected $loginUri = 'https://api.weixin.qq.com/sns/jscode2session?';

    public function __construct($option)
    {
        foreach ($option as $key=>$value){
            $this->$key = $value;
        }
    }

    /**
     * @param $code
     * @return mixed
     * @throws WxLoginException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function login($code){
        $option = [
            'appid'=>$this->appid,
            'secret'=>$this->secret,
            'grant_type'=>$this->grant_type,
            'js_code'=>$code
        ];
        $client = new Client(['verify'=>false]);
        $res = $client->request('GET',$this->loginUri.http_build_query($option));
        if ($res->getStatusCode() == 200){
            $response = json_decode($res->getBody());

            if (!isset($response->errcode)){
                return $response;
            }
            throw new WxLoginException($response->errmsg,$response->errcode);
        }
        throw new WxLoginException($res->getStatusCode(),$res->getBody());
    }


    /**
     * 检验数据的真实性，并且获取解密后的明文.
     * @param $sessionKey
     * @param $encryptedData string 加密的用户数据
     * @param $iv string 与用户数据一同返回的初始向量
     * @param $data string 解密后的原文
     *
     * @return void 成功0，失败返回对应的错误码
     * @throws WxException
     */
    public function decryptData( $sessionKey,$encryptedData, $iv, &$data )
    {
        if (strlen($sessionKey) != 24) {
            throw new WxException();
        }
        $aesKey=base64_decode($sessionKey);


        if (strlen($iv) != 24) {
            throw new WxException();
        }
        $aesIV=base64_decode($iv);

        $aesCipher=base64_decode($encryptedData);

        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

        $dataObj=json_decode( $result );
        if( $dataObj  == NULL )
        {
            throw new WxException();
        }
        if( $dataObj->watermark->appid != $this->appid )
        {
            throw new WxException();
        }
        $data = $result;
    }
}